\documentclass[12pt]{report}

% ok, prometto che la prossima volta dividerò in sottodocumenti

\usepackage[italian]{babel}
\usepackage[latin1]{inputenc}
\usepackage{url}
%\usepackage{biblatex}
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{caption}
\usepackage{float}
\usepackage{array}
\usepackage[margin=2cm]{geometry}
\usepackage{changepage}
\usepackage{color}
\usepackage{multirow}
\usepackage{hyperref}
\hypersetup{colorlinks=true,
		linkcolor=blue,
		urlcolor=blue,
		citecolor=blue,
		pdftitle={iaasFog - Analisi della visibilit\'a in condizioni di nebbia},
		pdfauthor={Stefano Cadario, Luca Cavazzana}}

\hyphenation{ransac}
	
%\bibliography{bib}

\begin{titlepage}
\begin{adjustwidth}{}{-3.7cm}
\begin{center}

\\[2.1cm]

\textsc{\Large Progetto di \\ Image Analysis and Synthesis \\ e \\ Argomenti avanzati di analisi di immagini}\\[0.5cm]
\textsc{\large A.A. 2010/2011}\\[0.5cm]

% Title
\\[1.5cm]
{ \huge \bfseries iaasFog}\\[0.4cm]
{ \huge \bfseries Analisi della visibilit\'a in \\ condizioni di nebbia}\\[0.4cm]
\\[1.5cm]

% Author and supervisor
\begin{minipage}{0.8\textwidth}
\begin{flushleft} \large
Stefano \textsc{Cadario},\\ mat. 724842\\
Luca \textsc{Cavazzana},\\ mat. 734498
\end{flushleft}
\end{minipage}
\begin{minipage}{0.8\textwidth}
\begin{flushright} \large
Prof.~Vincenzo \textsc{Caglioti}
\end{flushright}
\end{minipage}

%\vfill
\\[4cm]

% Bottom of the page
{\large 12 giugno 2011}

\end{center}
\end{adjustwidth}
\end{titlepage}


\begin{document}
%\maketitle

\tableofcontents

\chapter{Introduzione}

L'obbiettivo del progetto \`e estrarre un parametro numerico indicante la visibilit\`a in caso di nebbia utilizzando esclusivamente delle immagini riprese da una telecamera montata su un'automobile. La tecnica utilizzata si basa sull'analisi della variazione del contrasto delle features individuate in ogni frame dell'immagine con il fine di trovare il parametro $\lambda$ della funzione

$$k_fe^{-t_{\text{imp}}/\lambda}$$

\noindent Tale funzione deriva da una prima analisi teorica del problema in questione: la variabile $t_{\text{imp}}$ rappresenta il tempo che occorre ad una feature per attraversare il piano immagine, $k_f$ \`e il massimo livello di contasto di una generica feature $f$ in condizioni di visibilit\'a ideali, mentre il parametro $\lambda$, globale, pu\`o essere visto come il tempo d'impatto per una feature che sta emergendo dalla nebbia prendendo come riferimento l'istante in cui il livello di contrasto assume il valore $k_f/e$.\\
\noindent Il livello di visibilit\`a, che \`e una distanza, dovr\`a poi essere calcolato considerando la velocit\`a del veicolo come $\lambda v_t$.\\

\noindent I problemi affrontati nel corso di questo progetto consistono nello sviluppo di una tecnica performante per l'individuazione e il tracking di features il cui movimento relativo sia consistente con quello del veicolo, e trovare un metodo per il calcolo del contrasto e per la stima dei parametri in questione sufficientemente robusto ai livelli di rumore sui dati.\\
	 	
\noindent Un simile sistema potrebbe essere integrato fra i sensori di un veicolo, monitorando l'idoneit\`a della velocit\`a di crociera rispetto alle condizioni di visibilit\`a e ai tempi di reazione del conducente. Nel campo emergente dei veicoli autonomi, similmente, potrebbe vincolare il valore massimo di velocit\`a in base ai tempi di risposta, oppure potenziare la consapevolezza del sistema di analisi d'immagine fornendo un parametro per la stima della qualit\`a dei dati a seconda della distanza dell'elemento da cui sono state ricavati.



\chapter{Implementazione}

\noindent Il progetto \`e diviso in due parti: la prima, sviluppata in C\verb|++| in modo da poter sfruttare le funzioni messe a disposizione dalle librerie di OpenCV, si occupa dell'estrazione e del tracking delle features, del controllo della consistenza delle sequenze create, del calcolo del contrasto e dei tempi d'impatto. Seleziona infine le sequenze migliori in base alla distanza del vanishing point calcolato. Questa parte viene descritta pi\`u in dettaglio nelle sezioni da \ref{sect:track} a \ref{sect:contr}.\\

\begin{figure}[H]
	\centering
	\includegraphics[scale=0.7]{images/schemaCpp.pdf} 
	\label{diag:high}
	\caption{Fase di estrazione delle features e calcolo dei relativi contrasti sul tti}
\end{figure}

\noindent La seconda seconda parte, sviluppata in Matlab per sfruttare le funzioni di fitting, calcola il $\lambda$ globale come la mediana dei parametri stimati nelle migliori sequenze di dati, illustrato in dettaglio nella sottosezione \ref{sect:fit}.\\
Viene inoltre riportato nella sottosezione \ref{sect:rans} un secondo approccio basato su RANSAC, che avendo dato risultati interessanti \`e stato mantenuto ed \`e selezionabile come alternativa al metodo precedente.\\
Nella sottosezione \ref{sect:minmax} viene infine riportato per completezza l'approccio minMax, preso in considerazione ed infine abbandonato in quanto poco robusto.\\

\begin{figure}[H]
	\centering 
	\includegraphics[scale=0.7]{images/schemaMatlab.pdf} 
	\label{diag:high}
	\caption{A sinistra: fase di calcolo di $\lambda$ mediante fitting. A destra, ombreggiato: approccio alternativo basato su RANSAC.}
\end{figure}




\section{Tracking delle features}
\label{sect:track}

\noindent Il tracking delle features\footnote{All'interno di questo documento con il termine ``feature'' ci si riferisce ad una sequenza di corner associati ad uno stesso dettaglio nella scena in frame successivi.} deve individuare il maggior numero di features in ogni immagine, e nel contempo escludere gli outliers che influirebbero nei passaggi successivi dell'elaborazione.\\
L'analisi dei frame avviene in modo inverso rispetto al tempo, in modo da individuare le features quando sono ben visibili per poi inseguirle nei frame temporalmente precedenti, dove il riconoscimento \`e pi\`u difficoltoso a causa della nebbia.\\

\noindent Ad ogni frame viene eseguita la funzione \verb|cvGoodFeaturesToTrack| che individua la posizione dei corner con autovalori pi\`u alti e quindi con maggior probabilit\`a di essere individuati nei frame successivi. Nel frame seguente vengono quindi inseguiti utilizzando la funzione \verb|cvCalcOpticalFlowPyrLK|, che utilizzando l'algoritmo iterativo di \emph{Lucas-Kanade} ricalcola la nuova posizione di ogni feature.\\

\noindent Prima di aggiungere alla sequenza il nuovo punto individuato vengono effettuati dei controlli di coerenza: la nuova posizione deve avere direzione concorde con i punti antecedenti ed il nuovo passo deve essere maggiore dei precedenti. Una sequenza di corner \`e considerata valida se \`e inseguita per almeno cinque frame (per ottenere una migliore approsimazione del birapporto), in caso contrario viene eliminata. Se la feature \`e valida viene eseguito un controllo sulla cross-ratio dei punti, che deve essere prossima a 4/3. I punti trovati saranno comunque soggetti ad errori di posizione dovuti a diversi fattori e quindi non collineari: per rimediare viene quindi calcolata la retta di regressione, su cui verranno proiettati i punti per l'analisi del birapporto.\\

\noindent Il tracking dei corner diventa sempre pi\`u difficoltoso all'avvicinarsi al vanishing point a causa del calo dei livelli di contrasto dovuti alla nebbia, che riduce la possibilit\`a di individuazione; per ovviare a questo problema vengono calcolate le posizioni teoriche delle features utilizzando i punti nei frame precedenti e la cross ratio nota. Il tracking di una feature ha termine quando non si hanno pi\`u frame disponibili oppure quando lo step del nuovo punto \`e inferiore a $0.5$ pixel.

\section{Calcolo del vanishing point}
\label{sect:vp}
La posizione del vanishing point riveste un ruolo fondamentale nella risoluzione del problema poich\'e viene coinvolto sia nel filtro degli outliers, sia nel calcolo del tempo d'impatto di ogni feature.\\

\noindent Inizialmente \`e stato implementato un algoritmo che prevedeva l'individuazione di tutti i punti di intersezione tra rette e da questi ricavare il punto che minimizza la distanza con tutti gli altri. Questo approccio, sebbene abbia dato buoni risultati, si \`e rivelato troppo lento a causa della complessit\`a eccessiva del problema che richiedeva fino a $15$ secondi di elaborazione per $200$ features (complessit\`a $O\left(n^4\right)$).\\

\noindent Dopo un primo tentativo di ottimizzare l'algoritmo gi\'a esistente si \`e deciso di tentare un approccio completamente nuovo sfruttando RANSAC:

\begin{itemize}
\item	Ad ogni iterazione viene eletto casualmente un possibile candidato vanishing point calcolando l'intersezione delle rette rappresentanti due features, con il solo vincolo di essere all'interno del field of view dell'immagine.
\item	Per ogni retta viene calcolata la distanza dal vanishing point candidato. Tali distanze vengono ordinate in un vettore, la cui mediana sar\`a il rank associata a quel particolare vanishing point.
\item	Se il nuovo vanishing point ha un rank migliore dei precedenti viene eletto come nuovo best vanishing point.
\item	Il ciclo termina quando vengono analizzati un numero di intersezioni ritenuto sufficiente (il $5\%$ di tutte le possibili intersezioni tra rette).
\end{itemize}

\noindent Vengono infine scartate le features la cui retta di regressione dista pi\`u della distanza mediana rispetto al vanishing point eletto in quanto probabili outliers (viene mantenuta quindi solo la met\'a delle features).

\begin{figure}
	\begin{minipage}[b]{0.5\linewidth}
		\centering
		\includegraphics[scale=0.6]{images/iaasBefore.png}
		\captionof{figure}{Vanishing point calcolato mediante RANSAC.}
		\label{fig:vpBef}
	\end{minipage}
	\hspace{0.5cm}
	\begin{minipage}[b]{0.5\linewidth}
		\centering
		\includegraphics[scale=0.6]{images/iaasAfter.png}
		\captionof{figure}{Linee di fuga coerenti con il vanishing point calcolato.}
		\label{fig:vpAft}
	\end{minipage}
\end{figure}

\noindent L'algoritmo applicato a diversi set di dati ha restituito buoni risultati con tempi notevolmente ridotti (circa $1$ secondo di elaborazione per $200$ features) rispetto alla precedente implementazione meno efficiente (complessit\`a $O\left(n^2\log{n}\right)$).\\

\noindent Opzionalmente la posizione del vanishing point reale pu\`o essere affinata utilizzando SVD sul $50\%$ delle rette pi\`u vicine al vanishing point trovato in precedenza.\\

\begin{center}
	\includegraphics[scale=0.7]{images/iaasAfterArrow.png}
	\captionof{figure}{Flusso delle features inseguite.}
	\label{fig:vpAftArr}
\end{center}

\section{Calcolo del tempo all'impatto}

\noindent Dato un set di punti di coordinate $A$ e $B$ rappresentanti una feature in differenti immagini e conoscendo il frame rate $f$ delle telecamera \`e possibile calcolare il tempo d'impatto, ossia l'istante in cui la feature attraverser\`a il piano immagine, mediante il birapporto

$$ \text{cross}\left(i,a,b,v\right) = \frac{\overline{ia}}{\overline{ab}}\frac{\overline{av}}{\overline{iv}} = \frac{\overline{i'a'}}{\overline{a'b'}}\frac{\overline{a'v'}}{\overline{i'v'}} $$

\noindent dove $a$ e $b$ sono le coordinate delle feature, $v$ quelle del vanishing point e $i$ l'intersezione della traiettoria con il piano immagine, nel mondo reale e all'interno dei frames.\\
\noindent Essendo nel mondo reale le distanze rispetto al vanishing point infinite, cos\`i come quelle rispetto al piano della telecamera nelle immagini, la formula si semplifica in

$$ \frac{\overline{ia}}{\overline{ab}} = \frac{\overline{a'v'}}{\overline{a'b'}} $$

\noindent Dal momento che $\overline{a'v'}$ e $\overline{a'b'}$ sono noti, ed essendo $ab$ la distanza percorsa dal veicolo fra le due immagini ($velocit\`a/frame rate$), il tempo d'impatto pu\`o essere ottenuto come

$$ t_{i} = \frac{\overline{a'v'}}{\overline{a'b'}}\frac{\overline{ab}}{v} = \frac{\overline{a'v'}}{\overline{a'b'}}f^{-1} $$

\section{Calcolo del contrasto}
\label{sect:contr}

\noindent Per il calcolo del contrasto nell'intorno delle features sono stati presi in considerazione diversi approcci: oltre alla formule di Michelson e Weber, gi\`a sfruttate nelle precedenti fasi del progetto, \`e stato deciso di introdurre anche Root Mean Square, che calcola il livello di contrasto secondo la formula

$$ c\left(I_{M\times N}\right) = \sqrt{\frac{1}{MN}\sum_{i=1}^N\sum_{j=1}^M(i_{ij}-\bar{I})^2} $$

\noindent Dal momento che nel calcolo del valore contribuiscono tutti i pixel all'interno della finestra tale formula risulta essere molto pi\`u resistente al rumore rispetto alle precendenti, il cui risultato risulta essere influenzato dall'errore sul singolo pixel centrale per Weber, e dall'errore sui valori di min e max per Michelson.\\

\noindent Confrontando i valori ottenuti calcolando i livelli di contrasto utilizzando i diversi metodi si nota come RMS tenda a generare curve pi\`u smooth (figure \ref{fig:contr01}, \ref{fig:contr02} e \ref{fig:contr03}).\\

\noindent Una particolarit\`a di RMS \`e che, al contrario delle altre tecniche, il risultato dipende dallo spazio di colori utilizzato per rappresentare l'immagine (facilmente risolvibile riscalando rispetto alla profondit\`a del colore).

\begin{center}
	\includegraphics[scale=0.7, angle=90.0]{images/compContr1.png}
	\captionof{figure}{Confronto fra i valori di contrasto ottenuti mediante i differenti approcci.}
	\label{fig:contr01}
\end{center}
\begin{center}
	\includegraphics[scale=0.7, angle=90.0]{images/compContr2.png}
	\captionof{figure}{Confronto su nuove features.}
	\label{fig:contr02}
\end{center}
\begin{center}
	\includegraphics[scale=0.7, angle=90.0]{images/compContr3.png}
	\captionof{figure}{Confronto su nuove features.}
	\label{fig:contr03}
\end{center}




\section{Stima dei parametri}
\label{sect:stima}

\noindent Considerando l'equazione $k_fe^{-t_{\text{imp}}/\lambda}$ possiamo assumere la feature al tempo $0$ come completamente visibile (contrasto uguale a $k_f$), al contrario per $t_{\text{imp}}$ infinito abbiamo un livello di contrasto nullo. La variazione del parametro $\lambda$ agisce principalmente sulla dinamica con cui la feature cambia la propria visibilit\`a nel tempo: ad un aumento del valore corrisponde un appiattimento della curva che indicherebbe una variazione pi\`u lineare del contrasto (maggiore visibilit\`a), mentre per valori pi\`u piccoli abbiamo un incremento della pendenza della curva, portando ad un'improvvisa apparizione della feature prima dell'impatto. \\

\noindent L'unit\`a di misura di $\lambda$ \`e in secondi, e questo significa che tale valore \`e legato al tempo d'impatto invece che alla visibilit\`a in metri; per ottenere la visibilit\`a classica \`e possibile utilizzare la formula $vt=s$ che ci fornisce una stima della visibilit\`a in metri conoscendo la velocit\`a istantanea dell'auto. Sfortunatamente la misura di tale informazione nel video fornito non \`e disponibile, quindi ci si \`e limitati a considerare il tempo d'impatto medio rappresentato da $\lambda$ nell'ipotesi (forte) di velocit\`a costante.\\

\noindent Pi\`u precisamente per $t_{\text{imp}}=\lambda$ abbiamo il tempo d'impatto per la feature a partire dall'istante in cui il relativo contrasto assume il valore $k_fe^{-1}$. Tale valore \`e stato scelto come soglia per discriminare le feature visibili da quelle non in quanto conveniente da un punto di vista dei calcoli, e non perch\`e associato ad un concetto di visibilit\`a intuitivo in termini umani. Per far ci\`o si dovrebbe osservare sperimentalmente per quali valori di contrasto $c=qk_f$ delle features campione possono essere considerate come ``visibili'' per un occhio umano e dunque riscalare il $\lambda$ da noi fornito per $\alpha=-\log\left(q\right)$ come giustificato dalla seguente formula: $$qk_f = k_fe^{-t_{\text{imp,q}}/\lambda}$$ $$t_{\text{imp,q}} = -\lambda\log \left(q\right) = \alpha\lambda$$


\subsection{Fitting di $\lambda$}
\label{sect:fit}

\noindent Una prima tecnica adottata (e di fatto algoritmo selezionato di default nel codice sviluppato) \`e stata quella di sfruttare la funzione \verb|fit| di Matlab per estrarre il parametri $k_f$ e $\lambda_f$ che meglio descrivono ogni singola feature mediante il metodo dei minimi quadrati non lineare. Per ogni dato viene cos\`i calcolato l'errore rispetto alla curva generata, valore in base al quale verr\'a selezionata la met\'a dei dati migliori che verranno riutilizzati per approssimare nuovamente i parametri di una seconda curva esponenziale.\\

\begin{center}
	\includegraphics[scale=0.7]{images/twoFits.png}
	\captionof{figure}{Due fitting consecutivi: il blu usando tutta la sequenza di contrasti, in rosso la curva ottenuta usando solo il $50\%$ dei dati con errore migliore.}
	\label{fig:twoFits}
\end{center}

\noindent Fra i nuovi $\lambda_f$ calcolati vengono selezionati quelli associati al quartile delle migliori curve (meno affette da rumore), scelte in base ad un valore calcolato mediante diversi approcci:

\begin{itemize}
	\item	\emph{errore primo/secondo fitting}: l'errore viene calcolato come media dei rapporti fra l'errore e la proiezione del dato sulla prima/seconda curva approssimante calcolata.
	\item	\emph{variazione dell'errore}: nell'ipotesi di un buon set di dati la variazione dell'errore medio non dovrebbe essere molto grande. Viene quindi tenuta in considerazione la differenza fra gli errori dei dati sulle due curve (prossima a $0$ per buone features) o il loro rapporto (prossimo a $1$).
	\item	\emph{errore integrale}: sempre nell'ipotesi che per un buon set di dati la variazione fra le due curve \`e minima, viene calcolata la variazione sui parametri. Per aggregare i due valori viene considerata la differenza fra l'area delle due curve, calcolata come $$\left|\int^{\infty}_0\left(k_1e^{-t_{\text{imp}}/\lambda_1} - k_2e^{-t_{\text{imp}}/\lambda_2}\right)dt\right| =$$ $$= \left|\left[ k_2\lambda_2e^{-t_{\text{imp}}/\lambda_2} - k_1\lambda_1e^{-t_{\text{imp}}/\lambda_1} \right]^\infty_0\right| =$$ $$ = \left|k_2\lambda_2 - k_1\lambda_1\right|$$
\end{itemize}

\noindent L'ultimo approccio appare essere quello pi\`u robusto, ed \`e quello selezionato di default nel codice. Il $\lambda$ globale viene cos\`i calcolato come la mediana di quelli delle features selezionate.




\subsection{Normalizzazione mediante fitting di $k$ e RANSAC}
\label{sect:rans}

\noindent Un'altra tecnica sperimentata (selezionabile come algoritmo alternativo a quello descritto nella sezione precedente) consiste nel calcolare il parametro $k_f$ della curva che minimizza l'errore su ogni singola feature.\\

\begin{figure}[H]
	\centering
	\includegraphics[scale=0.6]{images/fitting.png}
	\captionof{figure}{Fitting e rescaling di una singola feature.}
	\label{fig:fitting}
\end{figure}

\noindent Tale parametro viene utilizzato per normalizzare features con differenti valori di contrasto ``intrinseco'' (ovvero il massimo livello che otterremmo in condizioni ideali, senza nebbia): utilizzando $c_{i,f}/k_f$ possiamo cos\`i considerare sulla funzione discreta solo il contributo della nebbia, permettendoci di aggregare i contrasti di diverse features e stimare il parametro $\lambda$ globale sulla formula $ c\left(t_{\text{imp}}\right) = e^{-t_{\text{imp}}/\lambda} $ mediante RANSAC.\\

\noindent Questa implementazione di RANSAC seleziona a caso il $25\%$ dei set disponibili: i valori di contrasto vengono aggregati, ordinati in base al tempo d'impatto ed infine usati per stimare il $\lambda$ globale usando il parametro della curva approssimante. Per tale parametro verr\`a poi calcolato il set di consenso ed il relativo errore, iterando il processo come da manuale.\\

\begin{figure}[H]
	\centering
	\includegraphics[scale=0.55]{images/ransac1}
	\captionof{figure}{In blu i livelli di contrasto di tutte le features, in rosso quelli del modello e in giallo la curva approssimante candidata.}
	\label{fig:tryLam}
\end{figure}

\noindent Il difetto di questo approccio \`e che vengono presi in considerazione anche dati molto rumorosi, che influiscono in parte sulla bont\`a del risultato.

\begin{figure}[H]
	\centering
	\includegraphics[scale=0.55]{images/ransacWin}
	\captionof{figure}{Miglior curva calcolata da RANSAC. In rosso i valori del modello eletto.}
	\label{fig:ransac}
\end{figure}





\subsection{Stima di $\lambda$ mediante minMax (deprecato)}
\label{sect:minmax}

\noindent Definita la formula del contrasto per ogni feature come

$$ c_{i,f} = k_fe^{-t_{i,f}/\lambda} $$

\noindent il parametro $k_f$ risulta essere costante all'interno di ogni singola sequenza di corner, mentre $\lambda$ \`e globale.\\
\noindent Sfruttando $k_f$ \`e possibile imporre la seguente uguaglianza fra due campioni di una stessa feature in modo da stimare il parametro $\lambda$ utilizzando i livelli di contrasto massimo e minimo (ed i relativi tempi all'impatto):

$$ c_1e^{t_1/\lambda} = c_2e^{t_2/\lambda} $$
$$ \lambda = \frac{t_2-t_1}{\log\frac{c_1}{c_2}} $$

\noindent A questo punto viene introdotto un primo semplice criterio atto ad eliminare features eccessivamente rumorose: ricordando che i dati sono ordinati sul tempo d'impatto (e quindi il contrasto risulter\`a essere una funzione decrescente) vengono ignorate features la cui differenza fra gli indici dei valori di contrasto minimo e massimo non \`e sufficientemente grande (nel nostro caso deve essere superiore alla met\`a del numero di corners all'interno del set).\\

\noindent Successivamente si pu\`o procedere al calcolo di un $\lambda$ globale in base a quelli stimati calcolandone la media o la mediana.\\

\noindent Tale approccio tuttavia, per quanto computazionalmente leggero, \`e stato abbandonato a causa dell'eccessiva sensibilit\`a all'errore sui dati (dal momento che spesso vengono selezionati come valori di min e max proprio degli outliers). Gli altri due approcci invece facendo uso di una maggiore quantit\`a di dati risultano essere molto pi\`u robusti, ma pagano in termini di prestazioni a causa della complessit\`a dei fitting delle curve.






\chapter{Risultati sperimentali}

\noindent I test sono stati eseguiti sulla sequenza di immagini fornite, consistenti in 113 frames estratti da un video acquisito mediante una telecamera in condizioni di nebbia. Di tale filmato tuttavia non sono noti parametri quali il framerate e la velocit\`a del veicolo; per ovviare a queste incognite sono state fatte diverse assunzioni:
\begin{itemize}
	\item	framerate a 30fps: una diversa frequenza d'acquisizione porterebbe a calcolare diversi tempi d'impatto, ma i valori rimarrebbero comunque congruenti fra di loro. Molto pi\`u rilevante \`e che il framerate si mantenga costante per tutto il filmato.
	\item	moto rettilineo: necessario per semplificare il tracking delle features. Ispezionando il filmato tuttavia si notano delle vistose oscillazioni, possibili cause di problemi in fase di tracking.
	\item	velocit\'a costante: il tempo all'impatto medio (in secondi) si relaziona alla visibilit\`a (in metri) mediante la velocit\`a del veicolo, parametro purtroppo non disponibile. In mancanza di migliori soluzioni questo valore \`e stato ipotizzato come costante, in modo da poter considerare il tempo d'impatto come stima della velocit\`a. Sfortunatamente questa assunzione non appare essere realistica, rendendo incongruenti i tempi calcolati (\`e infatti possibile ottenere uno stesso tti in condizioni di visibilit\`a peggiori semplicemente rallentando).
\end{itemize}
\noindent Come si nota dal campione di immagini mostrate in figura \ref{fig:video} la visibilit\`a migliora nel corso della sequenza.\\

\noindent A causa di risultati poco congruenti registrati nei test mostrati nelle sezioni \ref{fittest} e \ref{ransactest} potenzialmente riconducibili ad una violazione della terza ipotesi \`e stato deciso di acquisire appositamente dei nuovi filmati ad una velocit\`a nota e costante, anche se in condizioni di visibilit\`a ideali (vista la stagione), annotando tutti i parametri necessari per completare i test.\\


\newcommand{\videoScale}{0.5}
\begin{figure}[H]
\centering
\begin{tabular}{ccc}
	\includegraphics[scale=\videoScale]{images/frame0000.jpg} & \includegraphics[scale=\videoScale]{images/frame0010.jpg} & \includegraphics[scale=\videoScale]{images/frame0020.jpg}\\
	frame0000 & frame0010 & frame0020 \\
	\includegraphics[scale=\videoScale]{images/frame0030.jpg} & \includegraphics[scale=\videoScale]{images/frame0040.jpg} & \includegraphics[scale=\videoScale]{images/frame0050.jpg}\\
	frame0030 & frame0040 & frame0050 \\
	\includegraphics[scale=\videoScale]{images/frame0060.jpg} & \includegraphics[scale=\videoScale]{images/frame0070.jpg} & \includegraphics[scale=\videoScale]{images/frame0080.jpg}\\
	frame0060 & frame0070 & frame0080 \\
	\includegraphics[scale=\videoScale]{images/frame0090.jpg} & \includegraphics[scale=\videoScale]{images/frame0100.jpg} & \includegraphics[scale=\videoScale]{images/frame0110.jpg}\\
	frame0090 & frame0100 & frame0110 \\
\end{tabular}
\caption{Campioni estratti dalla sequenza di immagini fornite. Si noti come le condizioni di visibilit\`a migliorano.}
\label{fig:video}
\end{figure}

\section{Calcolo del vanishing point e tracking delle features}

\noindent Le figure \ref{fig:vp15}, \ref{fig:vp25} e \ref{fig:vp50} rappresentano il risultato dell'elaborazione dell'algoritmo sul calcolo del vanishing point su differenti sezioni del video con nebbia: l'algoritmo restituisce risultati tanto migliori quanto pi\`u sono le features disponibili, a loro volta dipendenti dal numero di frames; mentre per pochi frames (quindici) il calcolo del vanishing point \`e affetto da errori pi\`u o meno grandi, per tracking pi\`u lunghi (oltre i trenta frames) l'affidabilit\`a dell'algoritmo migliora notevolmente.\\

\noindent Nelle immagini poste a destra \`e possibile verificare come la met\`a delle linee di fuga individuate venga eliminata dal set perch\'e troppo lontana dal vanishing point trovato.\\

\newcommand{\imTrackScale}{0.7}
\begin{figure}[H]
\begin{minipage}[c]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imTrackScale]{images/bF_0000_15.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0020_15.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0040_15.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0060_15.png}
\end{minipage}
\begin{minipage}[c]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imTrackScale]{images/aF_0000_15.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0020_15.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0040_15.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0060_15.png}
\end{minipage}
\caption[short]{A sinistra: linee di fuga per 15 frames a partire dalle immagini 0, 20, 40 e 60. A destra: stesse features dopo il filtro sul vanishing point.}
\label{fig:vp15}
\end{figure}

\begin{figure}[H]
\begin{minipage}[c]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imTrackScale]{images/bF_0000_25.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0020_25.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0040_25.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0060_25.png}
\end{minipage}
\begin{minipage}[c]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imTrackScale]{images/aF_0000_25.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0020_25.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0040_25.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0060_25.png}
\end{minipage}
\caption[short]{A sinistra: linee di fuga per 25 frames a partire dalle immagini 0, 20, 40 e 60. A destra: stesse features dopo il filtro sul vanishing point.}
\label{fig:vp25}
\end{figure}

\begin{figure}[H]
\begin{minipage}[c]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imTrackScale]{images/bF_0000_50.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0020_50.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0040_50.png}
	\includegraphics[scale=\imTrackScale]{images/bF_0060_50.png}
\end{minipage}
\begin{minipage}[c]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imTrackScale]{images/aF_0000_50.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0020_50.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0040_50.png}
	\includegraphics[scale=\imTrackScale]{images/aF_0060_50.png}
\end{minipage}
\caption[short]{A sinistra: linee di fuga per 50 frames a partire dalle immagini 0, 20, 40 e 60. A destra: stesse features dopo il filtro sul vanishing point.}
\label{fig:vp50}
\end{figure}

\noindent L'algoritmo \`e stato testato con diversi punti di partenza e diverse lunghezze di inseguimento, allo scopo di osservare il numero di features restituite. Dal momento che la presenza di RANSAC in fase di calcolo del vanishing point porta ad una certa variabilit\`a del risultato \`e stato considerato il valore medio su dieci esecuzioni per ogni condizione iniziale.\\
\noindent I risultati nella tabella \ref{tabNum} mostrano come il numero di feature estratte aumenti con la lunghezza del tracking e con il migliorare delle condizioni di visibilit\`a. La varianza sul numero di features a parit\`a di condizioni iniziali \`e minima.

\begin{table}[H]
\begin{center}
\begin{tabular}{|c|c|c|c|c|}
	\hline
	& 15 & 25 & 35 & 50 \\ \hline
	Images/frame0000.jpg & 11 (0) & 13 (0) & 19.6 (0.84) & 22.5 (0.71)\\ \hline
	Images/frame0020.jpg & 15 (0.82) & 17.9 (1.1) & 18.3 (1.4) & 28 (0)\\ \hline
	Images/frame0040.jpg & 6 (0) & 18 (0) & 25 (0) & 24.5 (1.6)\\ \hline
	Images/frame0060.jpg & 24 (0) & 22.8 (1) & 22 (0) & 23 (0)\\ \hline
\end{tabular}
\caption{Numero medio (e deviazione standard) di features estratte dalla sequenza di immagini su dieci iterazioni. Sulle righe l'immagine di partenza, sulle colonne il numero di frame analizzati.}
\label{tabNum}
\end{center}
\end{table}



\newpage
\section{Tempi d'impatto}
\noindent Allo scopo di determinare l'affidabilit\`a dei tempi d'impatto calcolati si \`e deciso di allestire un test per confrontarli con quelli reali utilizzando uno dei nuovi filmati acquisiti: una volta selezionato un insieme di features inseguite correttamente ne viene calcolato il tempo d'impatto rispetto al punto in cui \`e stato acquisito il primo frame (uguale al tti calcolato in una qualsiasi immagine $i$ pi\`u il tempo di frame moltiplicato per $i-1$), valore che verr\`a confrontato con quello effettivo ottenuto dividendo la distanza reale\footnote{In mancanza di strumenti appositi le misurazioni sono state effettuate usando Google Earth.} dell'elemento che ha generato la feature per la velocit\`a del veicolo.\\

\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|}
	\hline
	distanza & tti reale & \begin{minipage}{2.5cm}\centering tti calcolato al frame 0 \end{minipage}& errore\\[6pt] \hline
	17m	& 1.53s	& 1.73s	& 0.2s	\\ \hline
	19m	& 1.71s	& 1.9s	& 0.19s	\\ \hline
	20m	& 1.8s	& 2.08s	& 0.28s	\\ \hline
	21m	& 1.89s	& 2.4s	& 0.51s	\\ \hline
	24m	& 2.16s	& 2.22s	& 0.06s	\\ \hline
	32m	& 2.88s	& 2.72s	& 0.16s	\\ \hline
	46m	& 4.14s	& 4.32s	& 0.18s	\\ \hline
	46m	& 4.14s	& 4.76s	& 0.62s	\\ \hline
	46m	& 4.14s	& 5.08s	& 0.94s	\\ \hline
	46m	& 4.14s	& 4.26s	& 0.12s	\\ \hline
	64m	& 5.76s	& 3.86s	& 1.9s	\\ \hline
	64m	& 5.76s	& 5.34s	& 0.42s	\\ \hline

\end{tabular}
\caption{Valori ottenuti viaggiando ad una velocit\`a di 40 km/h.}
\end{table}

\noindent I risultati per i livelli di precisione dei valori considerati (precisione del tachimetro analogico nel misurare la velocit\`a, precisione con cui \`e stata ricostruita la posizione del veicolo nel primo frame, precisione delle distanze misurate) possono considerarsi ampiamente soddisfacenti.\\

\newcommand{\ttiScale}{0.304}
\begin{table}[H]
\centering
\begin{tabular}{|@{}c@{}|@{}c@{}c@{}|@{}c|}
	\hline
	\begin{minipage}[H]{0.35\linewidth}\includegraphics[scale=\ttiScale]{images/tti1.png} \end{minipage} & 
	\begin{minipage}[H]{0.13\linewidth} \begin{tabular}{l} dist: 32m \\ tti_r: 2.88s \\ tti_0: 2.72s \\ err : 0.16s \\ \end{tabular}\end{minipage} & 
	\begin{minipage}[H]{0.35\linewidth}\includegraphics[scale=\ttiScale]{images/tti2.png} \end{minipage} & 
	\begin{minipage}[H]{0.13\linewidth} \begin{tabular}{l} dist: 24m \\ tti_r: 2.16s \\ tti_0: 2.22s \\ err : 0.06s \\ \end{tabular}\end{minipage} \\
	\hline
	\begin{minipage}[H]{0.35\linewidth}\includegraphics[scale=\ttiScale]{images/tti3.png} \end{minipage} & 
	\begin{minipage}[H]{0.13\linewidth} \begin{tabular}{l} dist: 46m \\ tti_r: 4.14s \\ tti_0: 5.08s \\ err : 0.94s \\ \end{tabular}\end{minipage} & 
	\begin{minipage}[H]{0.35\linewidth}\includegraphics[scale=\ttiScale]{images/tti4.png} \end{minipage} & 
	\begin{minipage}[H]{0.13\linewidth} \begin{tabular}{l} dist: 19m \\ tti_r: 1.71s \\ tti_0: 1.9s \\ err : 0.19s \\ \end{tabular}\end{minipage} \\
	\hline
	\begin{minipage}[H]{0.35\linewidth}\includegraphics[scale=\ttiScale]{images/tti5.png} \end{minipage} & 
	\begin{minipage}[H]{0.13\linewidth} \begin{tabular}{l} dist: 20m \\ tti_r: 1.8s \\ tti_0: 2.08s \\ err : 0.28s \\ \end{tabular}\end{minipage} & 
	\begin{minipage}[H]{0.35\linewidth}\includegraphics[scale=\ttiScale]{images/tti6.png} \end{minipage} & 
	\begin{minipage}[H]{0.13\linewidth} \begin{tabular}{l} dist: 64m \\ tti_r: 5.76s \\ tti_0: 3.86s \\ err : 1.9s \\ \end{tabular}\end{minipage} \\
	\hline
	\begin{minipage}[H]{0.35\linewidth}\includegraphics[scale=\ttiScale]{images/tti7.png} \end{minipage} & 
	\begin{minipage}[H]{0.13\linewidth} \begin{tabular}{l} dist: 46m \\ tti_r: 4.14s \\ tti_0: 4.32s \\ err : 0.18s \\ \end{tabular}\end{minipage} & 
	\begin{minipage}[H]{0.35\linewidth}\includegraphics[scale=\ttiScale]{images/tti8.png} \end{minipage} & 
	\begin{minipage}[H]{0.13\linewidth} \begin{tabular}{l} dist: 64m \\ tti_r: 5.76s \\ tti_0: 5.34s \\ err : 0.42s \\ \end{tabular}\end{minipage} \\
	\hline
\end{tabular}
\caption{Valori ottenuti viaggiando ad una velocit\`a di 40 km/h. In giallo la feature inseguita.}
\end{table}


\newpage
\section{Stima di $\lambda$ mediante fitting}
\label{fittest}

%% FIXME VISUALIZZAZIONE DELLE FEATURES -------------------

\noindent Le figure \ref{fig:feats1}, \ref{fig:feats2}, \ref{fig:feats3} e \ref{fig:feats4} rappresentano i livelli di contrasto (ordinati sul tempo d'impatto) e le relative curve approssimanti di ciascuna delle features trovate analizzando il set di cinquanta fra i frames forniti a partire da \verb|frame0000| del video con nebbia. Appare palese come i dati siano rumorosi, spesso portando a stimare parametri inverosimili.\\

\newcommand{\imFeat}{.42}
\begin{figure}[H]
\begin{minipage}[t]{0.5\linewidth}
	\centering
	feat1 - $k: 10.81, \lambda: 1.5 $\\
	\includegraphics[scale=\imFeat]{images/feat1}\\
	feat3 - $k: 8.05, \lambda: 2.62 $\\
	\includegraphics[scale=\imFeat]{images/feat3}\\
\end{minipage}
\begin{minipage}[t]{0.5\linewidth}
	\centering
	feat2 - $k: 10.3, \lambda: 1.69 $\\
	\includegraphics[scale=\imFeat]{images/feat2}\\
	feat4 - $k: 24.99, \lambda: 1.1 $\\
	\includegraphics[scale=\imFeat]{images/feat4}\\
\end{minipage}
\caption[short]{Features e relative curve fittate. I dati sono ordinati in base al tempo d'impatto.}
\label{fig:feats1}
\end{figure}

\begin{figure}[H]
\begin{minipage}[t]{0.5\linewidth}
	\centering
	feat5 - $k: 17.16, \lambda: 400.55 $\\
	\includegraphics[scale=\imFeat]{images/feat5}\\
	feat7 - $k: 18.09, \lambda: 1.22 $\\
	\includegraphics[scale=\imFeat]{images/feat7}\\
	feat9 - $k: 6.35, \lambda: 2.28 $\\
	\includegraphics[scale=\imFeat]{images/feat9}\\
\end{minipage}
\begin{minipage}[t]{0.5\linewidth}
	\centering
	feat6 - $k: 3.76, \lambda: 43672 $\\
	\includegraphics[scale=\imFeat]{images/feat6}\\
	feat8 - $k: 6.17, \lambda: 2.24 $\\
	\includegraphics[scale=\imFeat]{images/feat8}\\
	feat10 - $k: 402.16, \lambda: 0.61 $\\
	\includegraphics[scale=\imFeat]{images/feat10}\\
\end{minipage}
\caption[short]{Features e relative curve fittate. I dati sono ordinati in base al tempo d'impatto.}
\label{fig:feats2}
\end{figure}

\begin{figure}[H]
\begin{minipage}[t]{0.5\linewidth}
	\centering
	feat11 - $k: 12.4, \lambda: 0.91 $\\
	\includegraphics[scale=\imFeat]{images/feat11}\\


	feat13 - $k: 16.76, \lambda: 3.04 $\\
	\includegraphics[scale=\imFeat]{images/feat13}\\
	feat15 - $k: 21.28, \lambda: 1.09 $\\
	\includegraphics[scale=\imFeat]{images/feat15}\\
\end{minipage}
\begin{minipage}[t]{0.5\linewidth}
	\centering
	feat12 - $k: 11.65, \lambda: 1.4 $\\
	\includegraphics[scale=\imFeat]{images/feat12}\\
	feat14 - $k: 10.11, \lambda: 12.4 $\\
	\includegraphics[scale=\imFeat]{images/feat14}\\
	feat16 - $k: 6.09, \lambda: 2.82 $\\
	\includegraphics[scale=\imFeat]{images/feat16}\\
\end{minipage}
\caption[short]{Features e relative curve fittate. I dati sono ordinati in base al tempo d'impatto.}
\label{fig:feats3}
\end{figure}

\begin{figure}[H]
\begin{minipage}[t]{0.5\linewidth}
	\centering
	feat17 - $k: 2.09, \lambda: 23824.37 $\\
	\includegraphics[scale=\imFeat]{images/feat17}\\
	feat19 - $k: 22.84, \lambda: 0.52 $\\
	\includegraphics[scale=\imFeat]{images/feat19}\\
	feat21 - $k: 179.3, \lambda: 0.13 $\\
	\includegraphics[scale=\imFeat]{images/feat21}\\
\end{minipage}
\begin{minipage}[t]{0.5\linewidth}
	\centering
	feat18 - $k: 2.04, \lambda: 2.63 $\\
	\includegraphics[scale=\imFeat]{images/feat18}\\
	feat20 - $k: 46.83, \lambda: 0.8 $\\
	\includegraphics[scale=\imFeat]{images/feat20}\\
	feat22 - $k: 38.25, \lambda: 0.73 $\\
	\includegraphics[scale=\imFeat]{images/feat22}\\
\end{minipage}
\caption[short]{Features e relative curve fittate. I dati sono ordinati in base al tempo d'impatto.}
\label{fig:feats4}
\end{figure}



%% DATI MIGLIORI E PEGGIORI ----------------------------------
\newapage
\noindent L'immagine \ref{fig:bestIntErr} invece illustra il quartile dei migliori dati calcolato usando l'area fra i due successivi fitting (ricordiamo che partiamo dall'idea che per buoni set le due curve non differiscono molto). In blu viene visualizzata la curva approssimante l'intero set di dati, mentre in rosso \`e evidenziata la met\`a dei dati con errore minore e la curva approssimante da questi ultimi ottenuta. Similmente, in figura \ref{fig:worstIntErr} sono riportate le features con errore peggiore.\\

\noindent In base ai parametri $\lambda$ delle features migliori viene infine calcolata la mediana come valore globale, mostrato in figura \ref{fig:intErrHist}

\newcommand{\imFeatBW}{.48}
\begin{figure}[H]
\begin{minipage}[t]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imFeatBW]{images/best1}\\
	\includegraphics[scale=\imFeatBW]{images/best3}\\
	\includegraphics[scale=\imFeatBW]{images/best5}\\
\end{minipage}
\begin{minipage}[t]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imFeatBW]{images/best2}\\
	\includegraphics[scale=\imFeatBW]{images/best4}\\
	\includegraphics[scale=\imFeatBW]{images/best6}\\
\end{minipage}
\caption[short]{Migliori features secondo l'integrale dell'errore. In rosso evidenziati i dati considerati migliori e la nuova curva fittata.}
\label{fig:bestIntErr}
\end{figure}

\begin{figure}[H]
\begin{minipage}[t]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imFeatBW]{images/worst1}\\
	\includegraphics[scale=\imFeatBW]{images/worst3}\\
	\includegraphics[scale=\imFeatBW]{images/worst5}\\
\end{minipage}
\begin{minipage}[t]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imFeatBW]{images/worst2}\\
	\includegraphics[scale=\imFeatBW]{images/worst4}\\
	\includegraphics[scale=\imFeatBW]{images/worst6}\\
\end{minipage}
\caption[short]{Feature peggiori secondo l'integrale dell'errore. In rosso evidenziati i dati considerati migliori e la nuova curva fittata.}
\label{fig:worstIntErr}
\end{figure}

%% ISTOGRAMMI -----------------------------------

\begin{figure}[H]
	\centering
	\includegraphics[scale=.5]{images/intErrhistLamFit}
	\caption{Istogramma dei migliori $\lambda$ secondo l'integrale dell'errore (mediana: 1.22).}
	\label{fig:intErrHist}
\end{figure}

\noindent Sono infine stati analizzati i diversi valori di $\lambda$ restituiti dal presente algoritmo al variare del numero di frame analizzati e dal frame di partenza; ogni test \`e stato eseguito dieci volte per verificare anche la ripetibilit\`a dei risultati a causa della componente stocastica introdotta da RANSAC nella determinazione del punto di fuga.\\

\begin{table}[H]
\begin{center}
\begin{tabular}{|c|c|c|c|c|}
	\hline
	& 15 & 25 & 35 & 50 \\ \hline
	Images/frame0000.jpg & 0.512s (2.8e-07s) & 1.02s (0.13s) & 0.81s (0.26s) & 1.09s (0.021s)\\ \hline
	Images/frame0020.jpg & 0.945s (0.026s) & 0.999s (0.43s) & 0.888s (0.21s) & 1.03s (0.11s)\\ \hline
	Images/frame0040.jpg & 0.515s (0.079s) & 0.584s (0.053s) & 0.621s (0.1s) & 0.87s (0.12s)\\ \hline
	Images/frame0060.jpg & 0.591s (0.063s) & 0.68s (0.054s) & 0.774s (0.0086s) & 0.718s (0.065s)\\ \hline
\end{tabular}
\caption{Media (deviazione standard campionaria) del $\lambda$ calcolato mediante fitting. Sulle righe l'immagine di partenza, sulle colonne il numero di frame analizzati.}
\label{tabFit}
\end{center}
\end{table}

\noindent Osservando il filmato campione ci si aspetterebbe di osservare un miglioramento nelle condizioni di visibili\`a, cosa non evidente dai valori restituiti. Tali incongruenze potrebbero essere imputabili a possibili variazioni della velocit\`a nel veicolo usato per l'acquisizione del filmato, in violazione delle ipotesi fatte in partenza. Per questo motivo l'esperimento \`e stato ripetuto utilizzando i nuovi filmati acquisiti: diverse sequenze di immagini sono state estratte da un filmato ripreso con una videocamera a 30fps su di un veicolo alla velocit\`a costante di 60 km/h (precisione ottenibile con un tachimetro analogico) in condizioni di visibilit\`a ideali. Ciascuna sequenza \`e stata analizzata dieci volte.\\

\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|}
	\hline
	& 15 & 25 & 35 & 50 \\ \hline
	Images01/frame0000.png & 1.59s (0.17s) & 2s (0.56s) & 1.25s (0.16s) & 1.5s (0.39s)\\ \hline
	Images02/frame0000.png & 1.21s (0.074s) & 0.948s (0.033s) & 1.14s (0.13s) & 1.36s (0.077s)\\ \hline
	Images02/frame0060.png & 1.26s (0.35s) & 1.36s (0.084s) & 1.17s (0.081s) & 1.41s (0.14s)\\ \hline
	Images03/frame0000.png & 0.961s (0.98s) & 1.17s (0.046s) & 1.36s (0.19s) & 1.47s (0.26s)\\ \hline
	Images04/frame0000.png & 0.963s (0.031s) & 2.12s (0.082s) & 1.48s (0.35s) & 1.74s (0.24s)\\ \hline
	Images04/frame0040.png & 0.738s (0.0067s) & 1.72s (0.066s) & 1.7s (0.16s) & 1.49s (0.25s)\\ \hline
	Images05/frame0000.png & 1.22s (0.057s) & 1.65s (0.083s) & 2.04s (0.34s) & 1.47s (0.12s)\\ \hline
	Images05/frame0100.png & 0.829s (0.17s) & 0.888s (0.2s) & 1.18s (0.039s) & 0.801s (0.024s)\\ \hline
\end{tabular}
\caption{$\lambda$ medio e deviazione standard campionaria per diversi frame iniziali e lunghezze d'analisi.}
\end{table}

\noindent Si nota come all'aumentare della lunghezza dell'analisi le soluzioni tendano a convergere, essendo le condizioni di visibilit\`a sostanzialmente identiche nelle diverse sequenze. Per un $\lambda$ pari ad 1.5s ad una velocit\`a di 60 km/h la visibilit\`a risulta essere di 25m (si ricordi la definizione di ``visibilit\`a'' fornita nel all'inizio della sezione \ref{sect:stima}).\\

\noindent I dati grezzi ottenuti a seguito di quest'esperimento sono forniti allegati alla presente relazione nei files \verb|oldImgs.dat| e \verb|newImgs.dat|, dove sono salvate le matrici $\text{imgStart} \times \text{nFrames} \times 10$ le cui celle contengono per ogni iterazione le feature estratte, i valori di $\lambda$ ottenuti sia mediante fitting sia RANSAC ed i relativi tempi di calcolo. \\


\newpage
\section{Stima di $\lambda$ mediante RANSAC}
\label{ransactest}

\noindent Lo stesso set di features della sezione precedente viene utilizzato per stimare il $\lambda$ globale mediante RANSAC, di cui sono riportate alcune iterazioni nelle seguenti immagini.

\newcommand{\imFeatRan}{0.45}
\begin{figure}[H]
\begin{minipage}[t]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imFeatRan]{images/ransac1}\\
	\includegraphics[scale=\imFeatRan]{images/ransac3}\\
%	\includegraphics[scale=\imFeatRan]{images/ransac5}\\
\end{minipage}
\begin{minipage}[t]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imFeatRan]{images/ransac2}\\
	\includegraphics[scale=\imFeatRan]{images/ransac4}\\
%	\includegraphics[scale=\imFeatRan]{images/ransac6}\\
\end{minipage}
\caption[short]{Esempio di iterazioni di RANSAC. In blu i dati, in giallo le curva candidata, in rosso i campioni del relativo modello.}
\label{fig:ransac1}
\end{figure}

\begin{figure}[H]
\begin{minipage}[t]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imFeatRan]{images/ransac7}\\
	\includegraphics[scale=\imFeatRan]{images/ransac9}\\
	\includegraphics[scale=\imFeatRan]{images/ransac11}\\
\end{minipage}
\begin{minipage}[t]{0.5\linewidth}
	\centering
	\includegraphics[scale=\imFeatRan]{images/ransac8}\\
	\includegraphics[scale=\imFeatRan]{images/ransac10}\\
	\includegraphics[scale=\imFeatRan]{images/ransac12}\\
\end{minipage}
\caption[short]{Esempio di iterazioni di RANSAC. In blu i dati, in giallo le curva candidata, in rosso i campioni del relativo modello.}
\label{fig:ransac2}
\end{figure}

\begin{figure}[H]
	\centering
	\includegraphics[scale=.7]{images/ransacWin}
	\caption{Migliore curva trovata mediante RANSAC. $\lambda: 1.5$.}
	\label{fig:ransacWin}
\end{figure}

\noindent Allo scopo di verificare la variabilit\`a dei risultati di RANSAC \`e stato ripetuto il calcolo per cinquanta volte sullo stesso set di features.

\begin{figure}[H]
	\centering
	\includegraphics[scale=.6]{images/multiRansac}
	\caption{Istogramma dei $\lambda$ ottenuti eseguendo RANSAC cinquanta volte sullo stesso set di dati.}
	\label{fig:multiRansac}
\end{figure}

\noindent In modo analogo al caso precedente l'algoritmo \`e stato eseguito dieci volte sul video con nebbia per diverse condizioni iniziali, con risultati ancora una volta difficilmente interpretabili.

\begin{table}[H]
\begin{center}
\begin{tabular}{|c|c|c|c|c|}
	\hline
	& 15 & 25 & 35 & 50 \\ \hline
	Images/frame0000.jpg & 0.655s (0.0019s) & 0.729s (0.042s) & 0.943s (0.05s) & 1.45s (0.016s)\\ \hline
	Images/frame0020.jpg & 0.653s (0.012s) & 1.05s (0.34s) & 0.699s (0.25s) & 0.849s (0.014s)\\ \hline
	Images/frame0040.jpg & 0.711s (0.16s) & 0.539s (0.011s) & 0.587s (0.0055s) & 0.802s (0.023s)\\ \hline
	Images/frame0060.jpg & 0.382s (0.0056s) & 0.489s (0.029s) & 0.517s (0.052s) & 1.16s (0.38s)\\ \hline
\end{tabular}
\caption{Media (deviazione standard campionaria) del $\lambda$ calcolato mediante RANSAC. Sulle righe l'immagine di partenza, sulle colonne il numero di frame analizzati.}
\label{tabRans}
\end{center}
\end{table}

\noindent Il test \`e stato quindi ripetuto utilizzando le nuove sequenze di immagini acquisite:

\begin{table}[H]
\begin{center}
\begin{tabular}{|c|c|c|c|c|}
	\hline
	& 15 & 25 & 35 & 50 \\ \hline
	Images01/frame0000.png & 1.11s (0.28s) & 1.96s (0.6s) & 0.892s (0.02s) & 1.3s (0.22s)\\ \hline
	Images02/frame0000.png & 0.864s (0.13s) & 1.82s (0.15s) & 2.03s (0.15s) & 2.43s (0.28s)\\ \hline
	Images02/frame0060.png & 2.97s (0.18s) & 2.94s (1.4s) & 2.77s (0.9s) & 4.06s (0.98s)\\ \hline
	Images03/frame0000.png & 0.221s (0.069s) & 0.729s (0.059s) & 0.888s (0.027s) & 1.18s (0.071s)\\ \hline
	Images04/frame0000.png & 43.3s (28s) & 1.87s (0.44s) & 1.17s (0.15s) & 1.47s (0.16s)\\ \hline
	Images04/frame0040.png & 0.6s (0.015s) & 3.65s (0.13s) & 1.67s (0.41s) & 1.89s (0.33s)\\ \hline
	Images05/frame0000.png & 0.529s (0.15s) & 1.33s (0.057s) & 3.27s (1.2s) & 1.8s (0.24s)\\ \hline
	Images05/frame0100.png & 0.888s (0.048s) & 0.897s (0.3s) & 0.778s (0.16s) & 0.648s (0.062s)\\ \hline
\end{tabular}
\caption{Media (deviazione standard campionaria) del $\lambda$ calcolato mediante RANSAC sulle nuove sequenze acquisite. Sulle righe l'immagine di partenza, sulle colonne il numero di frame analizzati.}
\label{tab:ransNew}
\end{center}
\end{table}

\noindent I risultati, per quanto molto pi\`u variabili, sembrano avvicinarsi a quelli ottenuti nell'analogo test usanto il metodo di fitting. Un simile risultato era prevedibile dal momento che vengono usati meno filtri sulla bont\`a delle features. \\

\noindent Analogamente al sottoparagrafo precedente, i  dati grezzi ottenuti sono salvati nei files \verb|oldImgs.dat| e \verb|newImgs.dat|.




\section{Confronto}

\noindent Confrontando i risultati ottenuti sulle diverse immagini di prova si pu\`o notare come i risultati ottenuti mediante fitting siano molto pi\`u consistenti rispetto a quelli ottenuti mediante RANSAC. Questo non stupisce, dal momento che il primo algoritmo effettua un maggiore filtraggio sulla bont\`a delle features, al contrario RANSAC include nei calcoli anche dati pi\`u affetti da rumore.\\

\noindent Esaminando invece i tempi di calcolo si nota come RANSAC tenda ad essere pi\`u perfornante, anche se non in modo significativo: mentre il primo algoritmo richiede due fit per ogni feature, RANSAC ne richiede solo uno per la normalizzazione iniziale pi\`u un fit per ogni modello provato.\\

\begin{table}[H]
\begin{center}
\begin{tabular}{|c|c|c|c|c|}
	\hline
	& 15 & 25 & 35 & 50 \\ \hline
	Images/frame0000.jpg & 6.42/5.8 & 3.9/4.1 & 5.93/4.8 & 7.84/6\\ \hline
	Images/frame0020.jpg & 6.08/5.6 & 10.5/8.3 & 10.9/8.1 & 7.7/6.1\\ \hline
	Images/frame0040.jpg & 3.69/4.3 & 4.15/4.9 & 4.47/4.5 & 7.93/5.9\\ \hline
	Images/frame0060.jpg & 7.21/6.9 & 7.68/6.4 & 7.44/6.6 & 7.86/6.3\\ \hline
\end{tabular}
	\caption{Tempi di esecuzione medi di fit/RANSAC}
\end{center}
\end{table}

\chapter{Conclusioni e sviluppi futuri}

\noindent I risultati dei test hanno evidenziato come il problema sia fortemente influenzato dal numero di outliers derivati sia da un errato tracking delle features, sia da una non perfetta variazione del contrasto sulle features stesse. Il maggior sforzo computazionale \`e infatti da attribuire alla complessit\`a degli algoritmi utilizzati per escludere gli outliers in tutte le fasi dell'elaborazione in modo da avere valori attendibili in ogni condizione.\\

\noindent Sono stati analizzati diversi approcci ed algoritmi per la risoluzione del problema, e si \`e preferito, in ultimo, sacrificare il tempo di elaborazione in favore di una migliore affidabilit\`a dei risultati: gli algoritmi utilizzati sono in grado di individuare autonomamente le features migliori e scartare quelle meno buone, ottenendo dei buoni risultati come esposto nei capitoli precedenti.\\

\noindent Per l'estrazione ed il matching delle features sono state utilizzate le funzioni rese disponibili da OpenCV (sezione \ref{sect:track}) con buoni risultati. Dal punto di vista della rilevazione del punto di fuga l'approccio RANSAC si \`e rivelato vincente grazie alla sua buona affidabilit\`a mantenendo una complessit\`a di calcolo relativamente poco gravosa rispetto agli altri algoritmi testati (sezione \ref{sect:vp}). L'eseguibile C\verb|++| si occupa anche del calcolo del contrasto, per fare questo si avvale di RMS che nei test \`e risultato il pi\`u stabile (sezione \ref{sect:contr}). \\

\noindent La sezione Matlab si occupa di trovare il parametro $\lambda$: l'algoritmo descritto nella sezione \ref{sect:fit} \`e quello che ha dato i risultati migliori, utilizzando la funzione \verb|fit| di Matlab ed utilizzando il quantile 0.5 per escludere gli outliers.\\

\noindent Per quanto alcuni degli esperimenti usando il campione video fornito fossero inconcludenti a causa della mancanza di informazioni, i valori ottenuti nei test in condizioni di visibilit\`a ideale hanno comunque mostrato un certo grado di consistenza nei risultati ottenuti. Rimane tuttavia necessario effettuare ulteriori test in condizioni di nebbia avendo a disposizione tutte le necessarie informazioni per una corretta valutazione.\\

\noindent \`E inoltre necessario uno studio su come manipolare il $\lambda$ restituito in modo da conferirgli un significato pi\`u vicino al mondo delle percezioni umane, pi\'u intuitivo per l'utente, in modo simile a come suggerito nella sezione \ref{sect:stima}.\\

\noindent Ulteriori sviluppi futuri possono riguardare la reimplementazione in C\verb|++| del codice Matlab ed un'ottimizzazione degli algoritmi mirata a migliorarne le performance, eventualmente fino al punto di rendere possibile l'analisi direttamente su uno streaming video in realtime, senza le rielaborazioni successive del codice attualmente in uso. \\
In particolare \`e necessario implementare approcci pi\`u performanti per la stima dei parametri degli esponenziali, che allo stato attuale rappresenta il collo di bottiglia del sistema. Alcuni tentativi sono gi\`a stati abbozzati, come ad esempio utilizzando l'apposita opzione per gli esponenziali nel comando \verb|fit| o implementando la formula dei \href{http://mathworld.wolfram.com/LeastSquaresFittingExponential.html}{minimi quadrati} (riportato nel paragrafo \ref{subsect:fitExp}), ma per quanto molto pi\`u leggeri di un fit su generica formula questi algoritmi hanno mostrato una robustezza al rumore significativamente minore. Si dovr\`a cos\`i considerare un possibile trade-off tra tempo di calcolo e affidabilit\`a dei risultati. \\

\noindent L'aggiunta di un sistema stereoscopico potrebbe migliorare la fase di tracking delle feature, permettendo di introdurre un ulteriore filtro basato sul confronto della velocit\`a calcolata con quella effettiva del veicolo.\\


\chapter{Documentazione}


Viene qui presentata una panoramica delle funzioni realizzate. Per informazioni pi\`u dettagliate circa il loro utilizzo consultare l'\verb|help| delle funzioni.

\section[C++]{C\verb_++_}

\paragraph*{\verb_findFeatures:_} \`e la funzione principale dell'algoritmo, si occupa di chiamare le sottoprocedure dell'algoritmo

\paragraph*{\verb_iaasFindCorners:_} estrae dall'immagine i corner con autovalori pi\`u alti

\paragraph*{\verb_iaasTrackCorners:_} cerca di rintracciare i corner della prima immagine (gi\`a calcolati) nella seconda utilizzando l'algoritmo di \emph{Lucas-Kanade}

\paragraph*{\verb_verifyNewFeatureIsOk:_} verifica che un nuovo corner estratto sia coerente con quelli in precedenza rilevati

\paragraph*{\verb_getAroundContrast:_} calcola il contrasto nell'intorno di una feature usando RMS: $$ c\left(I_{M\times N}\right) = \sqrt{\frac{1}{MN}\sum_{i=1}^N\sum_{j=1}^M(i_{ij}-\bar{I})^2} $$

\paragraph*{\verb_verifyValidFeature:_} verifica che una sequenza di corner estratti sia coerente con il movimento e la cross ratio attesa

\paragraph*{\verb_printFeatures:_} scrive sul file la lista di features valide come:
\begin{verbatim}
	     primoFrame numeroFrame [xCoord yCoord contrasto tti]+
\end{verbatim}



\section{Matlab}

\paragraph*{\verb_iaas:_} funzione principale, parsa le feature generate dal codice C\verb|++| e chiede all'utente di selezionare l'algoritmo per il calcolo del $\lambda$ globale.

\paragraph*{\verb_parseFeatures:_} effettua il parsing del file di output generato da \verb|printFeatures| e restituisce una lista di struct contenente le informazioni di ogni feature: \verb|start| \`e il numero della prima immagine in cui appare la feature, \verb|num| il numero di frame nei quali viene inseguita, \verb|x|, \verb|y|, \verb|contr| e \verb|tti| sono array rappresentanti le coordinate, il contrasto e il tempo all'impatto della feature all'interno nell'i-esimo frame in cui vengono individuate. Nelle seguenti funzioni, quando si far\`a riferimento a liste di features si intender\`a cos\`i strutturate.

\paragraph*{\verb_fitLamContr:_} calcola i parametri della curva best fit sui dati di ciascuna delle features fornite in ingresso, aggiungendo il campo \verb|bestData| degli indici del $50\%$ dei corner con valori di contrasto con errore minimo rispetto alla stima. Viene poi aggiunto l'attributo \verb|pars| contenente i parametri del refitting usando il set \verb|bestData|. Vengono inoltre aggiunti diversi attributi per stimare la bont\`a del set di dati che compongono la singola feature (per una lista esaustiva si rimanda all'help della funzione), fra i quali in particolare ricordiamo \verb|intErr|, che calcola l'area fra le curve dei due successivi fit.

\paragraph*{\verb_estimateLamFit:_} seleziona il quartile delle migliori features usando uno degli attributi calcolati da \verb|fitLamContr| (nel nostro caso abbiamo preferito usare l'errore integrale) e usa la mediana dei $\lambda_f$ stimati per calcolare il parametro globale.

\paragraph*{\verb_fitNormContr:_} calcola il $\lambda$ globale mediante RANSAC dopo aver riscalato i livelli di contrasto di ogni feature in base al valore $k_f$ della curva best fit.

\paragraph*{\verb_normContrast:_} normalizza il contrasto di ogni set di features utilizzando diverse possibili tecniche (per una lista completa si rimanda all'help della funzione). Riportiamo l'opzione \verb|fit|, dal momento che \`e quella pi\`u efficace (e di fatto utilizzata all'interno del progetto), che riscala i contrasti delle singole features in base al $k_f$ della curva che meglio approssima il set di dati.

\paragraph*{\verb_myRansac:_} implementazione di RANSAC per calcolare il parametro $\lambda$ della funzione del contrasto dati in ingresso una lista di features.

\paragraph*{\verb_fitExp:_} calcola i parametri della curva approssimante usando i \href{http://mathworld.wolfram.com/LeastSquaresFittingExponential.html}{minimi quadrati per funzioni esponenziali}. Tale approccio risulta essere molto pi\`u leggero rispetto alla funzione \verb|fit| (con tempi d'esecuzione inferiori di diversi ordini di grandezza), ma appare risentire in modo molto maggiore della rumorosit\`a dei dati. Questa funzione di fatto non viene utilizzata nel codice realizzato, ma la sua integrazione andrebbe ulteriormente studiata visti i vantaggi a livello di tempo di calcolo.
\label{subsect:fitExp}

\paragraph*{\verb_inspectFeatures:_} stampa a video le sequenze di features per un'ispezione visiva, visualizzandone i relativi valori di contrasto.

\paragraph*{\verb_inspectContrasts:_} data una serie di features ne stampa a video i livelli di contrasto ordinati sul tempo d'impatto.

\paragraph*{\verb_michelsonContrast:_} date le coordinate di una feature e la relative immagine restituisce il livello di contrasto nell'intorno come $$c\left(I\right) = \frac{\max(I)-\min(I)}{\max(I)+\min(I)}$$

\paragraph*{\verb_rsmContrast:_} date le coordinate di una feature e la relativa immagine calcola il livello di contrasto nell'intorno come $$ c\left(I_{M\times N}\right) = \sqrt{\frac{1}{MN}\sum_{i=1}^N\sum_{j=1}^M(i_{ij}-\bar{I})^2} $$

\paragraph*{\verb_weberContrast:_} date le coordinate di una feature e la relative immagine calcola il livello di contrasto come $$c\left(i_{i,j}\right)= \frac{i_{i,j}-I_b}{I_b}$$ dove $I_b$ \`e il livello della nebbia.



\chapter{Installazione}
\noindent Il programma \`e stato sviluppato per mezzo di C\verb|++| e Matlab. Per la parte in C\verb|++| \`e necessario essere provvisti delle librerie di OpenCV.\\
L'ultima versione del codice \`e liberamente scaricabile mediante SVN dalla repository messa a disposizione su Google Code all'indirizzo \url{http://code.google.com/p/iaasfog}.
\section{OpenCV}

OpenCV (Open Source Computer Vision) \`e una libreria di funzioni per la computer vision, inizialmente sviluppata da Intel e ora distribuita sotto licenza open source. \`E possibile scaricare l'ultima versione all'indirizzo \url{http://sourceforge.net/projects/opencvlibrary/} \footnote{guida d'installazione ufficiale all'indirizzo \url{http://opencv.willowgarage.com/wiki/InstallGuide}}.

\subsection{Windows}

Per compilare la libreria \`e necessario installare gli header offerti da MinGW (\url{http://http://www.mingw.org/}) e CMake (\url{http://www.cmake.org/cmake/resources/software.html}).\\
\noindent Una volta assicuratisi che il path dei binari di MinGW \`e fra le variabili di ambiente configurare OpenCV mediante l'interfaccia di CMake.

\subsection{Linux / MacOSX}

\noindent Per l'installazione \`e necessario disporre di \verb|cmake|, inoltre devono essere soddisfatte le seguenti dipendenze:
\begin{itemize}
\item \verb|ffmpeg|
\item \verb|libxine-ffmpeg|
\item \verb|libavcodec-dev|
\item \verb|pgk-config|
\item \verb|libgtk2.0-dev|
\end{itemize}

\noindent reperibili mediante \verb|apt-get| o package manager.\\

\noindent Una volta scaricata e scompattata l'ultima versione di OpenCV (2.2.0 alla stesura del presente documento), creare una cartella dove verranno salvate le librerie configurate mediante \verb|cmake| e aprirla con una finestra di terminale. Nel nostro esempio la creeremo nella stessa cartella scompattata

\begin{verbatim}
	$ cd OpenCV2.2.0/
	$ mkdir release; cd release
\end{verbatim}

\noindent Lanciare quindi il comando

\begin{verbatim}
	$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local
	-D BUILD_PYTHON_SUPPORT=ON -D BUILD_EXAMPLES=ON ..
\end{verbatim}

\noindent per configurare la libreria. Il valore della flag \verb|CMAKE_INSTALL_PREFIX| sar\`a l'indirizzo in cui si vorr\`a poi installare OpenCV. Se i sorgenti non dovessero trovarsi nella directory superiore, sostituire i due punti con il path corretto.\\

\noindent A questo punto non rimane che compilare ed installare le librerie mediante i comandi

\begin{verbatim}
	$ make
	$ make install
\end{verbatim}

\noindent ed esportare il path nelle variabili di ambiente con il comando

\begin{verbatim}
	$ export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
	$ sudo ldconfig
\end{verbatim}

\noindent Se invece si preferisce non installare le librerie, esportare direttamente il path 

\begin{verbatim}
	$ export LD_LIBRARY_PATH=<opencv_dir>:$LD_LIBRARY_PATH
	$ sudo ldconfig
\end{verbatim}

\noindent dove \verb|<opencv_dir>| \`e la cartella dove abbiamo compilato le librerie, nel nostro caso\\ \verb|~/OpenCV-2.2.0/release|.

\section{Installazione ed esecuzione del programma}

\noindent Dopo aver scaricato il progratto da \url{http://code.google.com/p/iaasfog}, importare i sorgenti nella cartella C\verb|++| in Eclipse, importare gli header delle funzioni di OpenCV mediante Project $\rightarrow$ Properties  $\rightarrow$ C\slash C\verb|++| Editor $\rightarrow$ Settings $\rightarrow$ GCC C\verb|++| Compiler $\rightarrow$ Directories aggiungendo il percorso \verb|/usr/local/include/| e sotto GCC C\slash C\verb|++| Linker $\rightarrow$ Libraries le librerie \verb|opencv_core|, \verb|opencv_video|, \verb|opencv_highgui| e \verb|opencv_imgproc| in \verb|/usr/local/lib| (o qualunque path sia stato utilizzato per l'installazione).\\
Compilare.\\

\noindent In Matlab aggiungere il path degli m-file ed assicurarsi che il percorso specificato dalla varibile \verb|exec_path| in \verb|iaas.m| corrisponda alla cartella dell'eseguibile del codice C\verb|++|.\\
Per eseguire il programma lanciare nella console di Matlab il comando \verb|iaas [#]|, dove \verb|#|, opzionale, non far\`a visualizzare nessuna finestra se assente o uguale a \verb|0|, se uguale a \verb|1| visualizzer\`a una serie di grafici che mostrano le curve approssimanti, mentre per valori maggiori o uguali a \verb|2| mostrer\`a un numero maggiore di grafici (modalit\`a pensata principalmente per il debugging, l'eccessiva quantitat\'a di grafici rischia di risultare tediosa per l'utente).

%\printbibliography

\end{document}
